# -*- coding: utf-8 -*-

from odoo import models, fields, api, _
from odoo.exceptions import ValidationError


class CpqConfiguration(models.Model):
    _name = 'cpq.configuration'
    _description = '产品配置器'
    _rec_name = 'name'
    _order = 'create_date desc'
    
    # ============ 基础信息 ============
    name = fields.Char(
        string='配置名称',
        required=True,
        default='新配置'
    )
    
    product_tmpl_id = fields.Many2one(
        'product.template',
        string='产品模板',
        required=True,
        domain=[('is_configurable', '=', True)]
    )
    
    product_id = fields.Many2one(
        'product.product',
        string='产品变体',
        compute='_compute_product_id',
        store=True
    )
    
    version = fields.Char(
        string='版本号',
        default='1.0'
    )
    
    state = fields.Selection([
        ('draft', '草稿'),
        ('validated', '已验证'),
        ('approved', '已批准')
    ], string='状态', default='draft', required=True)
    
    active = fields.Boolean(
        string='有效',
        default=True
    )
    
    company_id = fields.Many2one(
        'res.company',
        string='公司',
        default=lambda self: self.env.company
    )
    
    # ============ 配置项 ============
    attribute_line_ids = fields.One2many(
        'cpq.configuration.line',
        'config_id',
        string='配置项'
    )
    
    # ============ 验证结果 ============
    is_manufacturable = fields.Boolean(
        string='可制造',
        compute='_compute_manufacturable',
        store=True
    )
    
    validation_message = fields.Text(
        string='验证消息',
        readonly=True
    )
    
    # ============ 输出 ============
    validated_bom_id = fields.Many2one(
        'mrp.bom',
        string='验证后的BOM'
    )
    
    # ============ 成本影响 ============
    total_cost_impact = fields.Monetary(
        string='总成本影响',
        compute='_compute_cost_impact',
        store=True,
        currency_field='currency_id'
    )
    
    currency_id = fields.Many2one(
        'res.currency',
        related='company_id.currency_id',
        string='货币'
    )
    
    # ============ 备注 ============
    description = fields.Text(
        string='描述'
    )
    
    notes = fields.Text(
        string='备注'
    )
    
    # ============ 计算字段 ============
    @api.depends('product_tmpl_id')
    def _compute_product_id(self):
        """获取产品变体"""
        for record in self:
            if record.product_tmpl_id:
                record.product_id = record.product_tmpl_id.product_variant_id
            else:
                record.product_id = False
    
    @api.depends('attribute_line_ids', 'attribute_line_ids.is_valid')
    def _compute_manufacturable(self):
        """计算是否可制造"""
        for record in self:
            if not record.attribute_line_ids:
                record.is_manufacturable = False
            else:
                # 检查所有配置项是否有效
                record.is_manufacturable = all(
                    line.is_valid for line in record.attribute_line_ids
                )
    
    @api.depends('attribute_line_ids', 'attribute_line_ids.cost_impact')
    def _compute_cost_impact(self):
        """计算总成本影响"""
        for record in self:
            record.total_cost_impact = sum(
                record.attribute_line_ids.mapped('cost_impact')
            )
    
    # ============ 验证方法 ============
    def action_validate_configuration(self):
        """验证配置的可制造性"""
        self.ensure_one()
        
        messages = []
        
        # 1. 检查必选项
        required_attributes = self.product_tmpl_id.attribute_line_ids.filtered(
            lambda l: l.required
        )
        configured_attributes = self.attribute_line_ids.mapped('attribute_id')
        
        for req_attr in required_attributes:
            if req_attr.attribute_id not in configured_attributes:
                messages.append(f'缺少必选配置项: {req_attr.attribute_id.name}')
        
        # 2. 应用规则验证
        rules = self.env['cpq.rule'].search([
            ('product_tmpl_id', '=', self.product_tmpl_id.id),
            ('rule_type', 'in', ['mandatory', 'exclusion', 'inclusion'])
        ])
        
        for rule in rules:
            if not self._evaluate_rule(rule):
                messages.append(rule.error_message or f'规则验证失败: {rule.name}')
        
        # 3. 更新验证结果
        if messages:
            self.validation_message = '\n'.join(messages)
            self.state = 'draft'
            raise ValidationError('\n'.join(messages))
        else:
            self.validation_message = '验证通过'
            self.state = 'validated'
            
            # 4. 生成BOM
            self._generate_bom_from_config()
        
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': '验证成功',
                'message': '配置验证通过，可以进行成本核算',
                'type': 'success',
                'sticky': False,
            }
        }
    
    def _evaluate_rule(self, rule):
        """评估规则"""
        # TODO: 实现规则评估逻辑
        # 这里需要根据rule.condition评估当前配置是否满足规则
        return True
    
    def _generate_bom_from_config(self):
        """根据配置生成BOM"""
        self.ensure_one()
        
        # 检查是否已有BOM
        if self.validated_bom_id:
            # 更新现有BOM
            bom = self.validated_bom_id
            bom.bom_line_ids.unlink()
        else:
            # 创建新BOM
            bom = self.env['mrp.bom'].create({
                'product_tmpl_id': self.product_tmpl_id.id,
                'product_qty': 1.0,
                'type': 'normal',
                'code': f'CPQ-{self.id}'
            })
            self.validated_bom_id = bom
        
        # 根据配置生成BOM行
        for config_line in self.attribute_line_ids:
            if config_line.bom_component_id:
                self.env['mrp.bom.line'].create({
                    'bom_id': bom.id,
                    'product_id': config_line.bom_component_id.id,
                    'product_qty': config_line.component_quantity or 1.0
                })
        
        return bom
    
    def action_approve(self):
        """批准配置"""
        self.ensure_one()
        if self.state != 'validated':
            raise ValidationError('只有已验证的配置才能批准！')
        self.state = 'approved'
    
    def action_reset_to_draft(self):
        """重置为草稿"""
        self.ensure_one()
        self.state = 'draft'
        self.validation_message = False

